//package com.example.ssm.config;
//
//import org.aspectj.lang.annotation.Aspect;
//import org.springframework.aop.Advisor;
//import org.springframework.aop.aspectj.AspectJExpressionPointcut;
//import org.springframework.aop.support.DefaultPointcutAdvisor;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//import org.springframework.transaction.PlatformTransactionManager;
//import org.springframework.transaction.TransactionDefinition;
//import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
//import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
//import org.springframework.transaction.interceptor.TransactionInterceptor;
//
//import javax.sql.DataSource;
//
//@Aspect
//@Configuration
//public class TransactionAdviceConfig {
//    private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.example.ssm.*.*.service.*.*(..)) or execution(* org.activiti.engine.*Service.*(..))";
//
//    @Primary
//    @Bean
//    public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
//        return new DataSourceTransactionManager(dataSource);
//    }
//
//    @Bean
//    public TransactionInterceptor txAdvice(@Qualifier("transactionManager") PlatformTransactionManager transactionManager) {
//        // 如果存在一个事务，则支持当前事务。如果没有事务则开启一个新的事务。
//        RuleBasedTransactionAttribute txAttrRequired = new RuleBasedTransactionAttribute();
//        txAttrRequired.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//
//        // 只读事务，不做更新操作，如果存在事务，则进入事务；否则，以非事务方式运行。
//        RuleBasedTransactionAttribute txAttrReadonly = new RuleBasedTransactionAttribute();
//        txAttrReadonly.setReadOnly(true);
//        txAttrReadonly.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
//
//        // 如果存在事务，则进入事务；否则，以非事务方式运行。
//        RuleBasedTransactionAttribute txAttrNone = new RuleBasedTransactionAttribute();
//        txAttrNone.setReadOnly(false);
//        txAttrNone.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
//
//        RuleBasedTransactionAttribute txAttrRequires_new = new RuleBasedTransactionAttribute();
//        txAttrRequires_new.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//
//        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
//
//        source.addTransactionalMethod("insert*", txAttrRequired);
//        source.addTransactionalMethod("update*", txAttrRequired);
//        source.addTransactionalMethod("delete*", txAttrRequired);
//        source.addTransactionalMethod("remove*", txAttrRequired);
//        source.addTransactionalMethod("save*", txAttrRequired);
//        source.addTransactionalMethod("add*", txAttrRequired);
//        source.addTransactionalMethod("flush*", txAttrRequired);
//        source.addTransactionalMethod("exec*", txAttrRequired);
//        source.addTransactionalMethod("runto*", txAttrRequired);
//        source.addTransactionalMethod("has*", txAttrRequired);
//        source.addTransactionalMethod("unfreeze*", txAttrRequired);
//        source.addTransactionalMethod("unpause*", txAttrRequired);
//        source.addTransactionalMethod("enable*", txAttrRequired);
//        source.addTransactionalMethod("next*", txAttrRequired);
//
//
//        source.addTransactionalMethod("select*", txAttrReadonly);
//        source.addTransactionalMethod("count*", txAttrReadonly);
//        source.addTransactionalMethod("query*", txAttrReadonly);
//        source.addTransactionalMethod("find*", txAttrReadonly);
//        source.addTransactionalMethod("list*", txAttrReadonly);
//        source.addTransactionalMethod("search*", txAttrReadonly);
//
//        source.addTransactionalMethod("*", txAttrNone);
//
//        source.addTransactionalMethod("executeBpm", txAttrRequires_new);
//        source.addTransactionalMethod("validateAfterHandlerCodeInfo", txAttrRequires_new);
//
//        return new TransactionInterceptor(transactionManager, source);
//    }
//
//    @Bean
//    public Advisor txAdviceAdvisor(@Qualifier("transactionManager") PlatformTransactionManager transactionManager) {
//        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
//        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
//        return new DefaultPointcutAdvisor(pointcut, txAdvice(transactionManager));
//    }
//}
